"""PPG处理器基础使用示例

展示如何使用PPG处理器进行基本的信号处理，包括：
1. 使用numpy数组输入
2. 使用字典输入
3. 使用PPGSignal对象输入
4. 选择不同的Pipeline
5. 查看处理结果

作者: PPG算法包开发团队
版本: 2.0.0
"""

import numpy as np
import logging
from typing import Dict, Any, Optional

try:
    from ..core.processor_manager import process_ppg_signal, create_ppg_pipeline, get_global_manager
    from ..core.data_types import PPGSignal, PPGResults
    from ..config.pipeline_config import PipelineConfig
    from ..config.default_configs import get_config_by_name
except ImportError:
    # 处理直接运行时的导入问题
    import sys
    from pathlib import Path
    sys.path.append(str(Path(__file__).parent.parent))
    from core.processor_manager import process_ppg_signal, create_ppg_pipeline, get_global_manager
    from core.data_types import PPGSignal, PPGResults
    from config.pipeline_config import PipelineConfig
    from config.default_configs import get_config_by_name

# 设置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


def basic_ppg_processing_example():
    """基础PPG处理示例
    
    演示最简单的PPG信号处理流程
    """
    print("=" * 60)
    print("PPG处理器基础使用示例")
    print("=" * 60)
    
    # 1. 生成模拟PPG信号
    print("\n1. 生成模拟PPG信号")
    sampling_rate = 100.0  # 100Hz采样率
    duration = 30.0  # 30秒
    t = np.linspace(0, duration, int(sampling_rate * duration))
    
    # 模拟PPG信号：基础心率70 BPM + 噪声
    heart_rate = 70  # BPM
    frequency = heart_rate / 60  # Hz
    
    # 生成基础PPG波形
    ppg_signal = np.sin(2 * np.pi * frequency * t)
    # 添加二次谐波（更真实的PPG形状）
    ppg_signal += 0.3 * np.sin(2 * np.pi * 2 * frequency * t)
    # 添加噪声
    noise = np.random.normal(0, 0.1, len(t))
    ppg_signal += noise
    
    print(f"生成信号长度: {len(ppg_signal)} 点")
    print(f"采样率: {sampling_rate} Hz")
    print(f"持续时间: {duration} 秒")
    print(f"模拟心率: {heart_rate} BPM")
    
    # 2. 使用numpy数组输入处理
    print("\n2. 使用numpy数组输入 - 自定义Pipeline")
    try:
        results_custom = process_ppg_signal(
            signal_data=ppg_signal,
            sampling_rate=sampling_rate,
            pipeline_name="custom_demo",
            pipeline_type="custom"
        )
        
        print(f"✓ 自定义Pipeline处理成功")
        print(f"  检测峰值数: {len(results_custom.peaks)}")
        print(f"  平均心率: {results_custom.mean_heart_rate:.1f} BPM")
        if results_custom.quality_results:
            print(f"  信号质量: {results_custom.quality_results.quality_grade}")
        
    except Exception as e:
        print(f"✗ 自定义Pipeline处理失败: {e}")
    
    # 3. 使用NeuroKit2 Pipeline（如果可用）
    print("\n3. 使用NeuroKit2 Pipeline")
    try:
        results_nk = process_ppg_signal(
            signal_data=ppg_signal,
            sampling_rate=sampling_rate,
            pipeline_name="neurokit2_demo",
            pipeline_type="neurokit2"
        )
        
        print(f"✓ NeuroKit2 Pipeline处理成功")
        print(f"  检测峰值数: {len(results_nk.peaks)}")
        print(f"  平均心率: {results_nk.mean_heart_rate:.1f} BPM")
        if results_nk.quality_results:
            print(f"  信号质量: {results_nk.quality_results.quality_grade}")
            
    except ImportError:
        print("✗ NeuroKit2未安装，跳过NeuroKit2 Pipeline演示")
    except Exception as e:
        print(f"✗ NeuroKit2 Pipeline处理失败: {e}")
    
    # 4. 使用字典输入
    print("\n4. 使用字典输入")
    signal_dict = {
        'data': ppg_signal,
        'sampling_rate': sampling_rate,
        'subject_id': 'demo_001',
        'session': 'baseline'
    }
    
    try:
        results_dict = process_ppg_signal(
            signal_data=signal_dict,
            pipeline_name="dict_demo",
            pipeline_type="custom",
            config="fast"  # 使用快速配置
        )
        
        print(f"✓ 字典输入处理成功")
        print(f"  检测峰值数: {len(results_dict.peaks)}")
        print(f"  平均心率: {results_dict.mean_heart_rate:.1f} BPM")
        
    except Exception as e:
        print(f"✗ 字典输入处理失败: {e}")
    
    # 5. 使用PPGSignal对象输入
    print("\n5. 使用PPGSignal对象输入")
    ppg_obj = PPGSignal(
        data=ppg_signal,
        sampling_rate=sampling_rate,
        metadata={'subject_id': 'demo_001', 'condition': 'rest'}
    )
    
    try:
        results_obj = process_ppg_signal(
            signal_data=ppg_obj,
            pipeline_name="object_demo",
            pipeline_type="custom",
            config="accurate"  # 使用精确配置
        )
        
        print(f"✓ PPGSignal对象处理成功")
        print(f"  检测峰值数: {len(results_obj.peaks)}")
        print(f"  平均心率: {results_obj.mean_heart_rate:.1f} BPM")
        
    except Exception as e:
        print(f"✗ PPGSignal对象处理失败: {e}")
    
    # 6. 显示详细结果
    print("\n6. 详细结果分析")
    if 'results_custom' in locals():
        analyze_results(results_custom, "自定义Pipeline")
    
    print("\n" + "=" * 60)
    print("基础示例完成")
    print("=" * 60)


def analyze_results(results, pipeline_name: str):
    """分析处理结果
    
    参数:
        results: PPG处理结果
        pipeline_name: Pipeline名称
    """
    print(f"\n--- {pipeline_name} 详细结果 ---")
    
    # 基本信息
    print(f"Pipeline名称: {results.pipeline_name}")
    print(f"原始信号长度: {len(results.original_signal)}")
    print(f"处理后信号长度: {len(results.processed_signal)}")
    
    # 峰值信息
    print(f"检测峰值数: {len(results.peaks)}")
    if len(results.peaks) > 0:
        peak_intervals = np.diff(results.peaks)
        print(f"峰值间隔 - 平均: {np.mean(peak_intervals):.1f}, 标准差: {np.std(peak_intervals):.1f}")
    
    # 心率信息
    if results.heart_rates is not None:
        print(f"心率统计:")
        print(f"  平均心率: {results.mean_heart_rate:.1f} BPM")
        print(f"  心率范围: {np.min(results.heart_rates):.1f} - {np.max(results.heart_rates):.1f} BPM")
        print(f"  心率变异性: {np.std(results.heart_rates):.1f} BPM")
    
    # HRV信息
    if results.hrv_results:
        hrv = results.hrv_results
        print(f"HRV指标:")
        print(f"  RMSSD: {hrv.rmssd:.2f} ms")
        print(f"  SDNN: {hrv.sdnn:.2f} ms")
        print(f"  pNN50: {hrv.pnn50:.2f} %")
        if hrv.lf_hf_ratio > 0:
            print(f"  LF/HF比值: {hrv.lf_hf_ratio:.2f}")
    
    # 质量信息
    if results.quality_results:
        quality = results.quality_results
        print(f"信号质量:")
        print(f"  总体评分: {quality.quality_score:.3f}")
        print(f"  质量等级: {quality.quality_grade}")
        print(f"  信噪比: {quality.snr:.2f} dB")
        print(f"  峰值规律性: {quality.peak_regularity:.3f}")
    
    # 处理信息
    if results.processing_info:
        print(f"处理信息: {len(results.processing_info)} 个步骤")
        for step, info in results.processing_info.items():
            if isinstance(info, dict) and 'duration' in info:
                print(f"  {step}: {info['duration']:.3f}s")


def demonstrate_pipeline_creation():
    """演示Pipeline创建和配置
    """
    print("\n" + "=" * 60)
    print("Pipeline创建和配置演示")
    print("=" * 60)
    
    # 1. 创建默认自定义Pipeline
    print("\n1. 创建默认自定义Pipeline")
    try:
        custom_pipeline = create_ppg_pipeline("custom")
        print(f"✓ 创建成功: {custom_pipeline.name}")
        print(f"  采样率: {custom_pipeline.sampling_rate} Hz")
        print(f"  配置名称: {custom_pipeline.config.name}")
    except Exception as e:
        print(f"✗ 创建失败: {e}")
    
    # 2. 使用预定义配置创建Pipeline
    print("\n2. 使用预定义配置")
    try:
        fast_pipeline = create_ppg_pipeline("custom", config="fast")
        print(f"✓ 快速配置Pipeline: {fast_pipeline.name}")
        
        accurate_pipeline = create_ppg_pipeline("custom", config="accurate")
        print(f"✓ 精确配置Pipeline: {accurate_pipeline.name}")
    except Exception as e:
        print(f"✗ 预定义配置创建失败: {e}")
    
    # 3. 使用自定义配置字典
    print("\n3. 使用自定义配置字典")
    custom_config = {
        "name": "my_custom_config",
        "sampling_rate": 125.0,
        "preprocessing": {
            "filtering": {
                "enabled": True,
                "low_cutoff": 0.5,
                "high_cutoff": 8.0
            }
        }
    }
    
    try:
        custom_pipeline = create_ppg_pipeline("custom", config=custom_config)
        print(f"✓ 自定义配置Pipeline: {custom_pipeline.name}")
        print(f"  采样率: {custom_pipeline.sampling_rate} Hz")
    except Exception as e:
        print(f"✗ 自定义配置创建失败: {e}")


if __name__ == "__main__":
    # 运行基础示例
    basic_ppg_processing_example()
    
    # 运行Pipeline创建演示
    demonstrate_pipeline_creation()